package tk.mybatis.simple.mapper;

import org.apache.ibatis.annotations.Param;
import tk.mybatis.simple.model.SysRole;
import tk.mybatis.simple.model.SysUser;

import java.util.List;

public interface UserMapper {
    /**
     * 通过 id 查询用户
     * @param id
     * @return
     */
    SysUser selectById(Long id);

    /**
     * 查询全部用户
     * 在定义接口中方法的返回值时，必须注意查询 SQL 可能返回的结果数量。当返回值最多只有 1 个结果的时候（可以 0 个），可以将接口返回值定义为 SysUser，而不是 List<SysUser>。
     * 当然，如果将返回值改为 List<SysUser> 或 SysUser[]，也没有问题，只是不建议这么做。当执行的 SQL 返回多个结果时，必须使用 List<SysUser> 或 SysUser[] 作为返回值，
     * 如果使用 SysUser，就会抛出 TooManyResultsException 异常。
     * @return
     */
    List<SysUser> selectAll();

    /**
     * 根据用户 id 获取用户拥有的所有角色
     * 返回的结果为角色集合，结果只有角色的信息，不包含额外的其他字段信息。这个方法会涉及 sys_user、sys_role 和 sys_user_role 这 3 个表，并且该方法写在任何一个对应的 Mapper 接口中都可以
     * @param userId
     * @return
     */
    List<SysRole> selectRolesByUserId(Long userId);

    /**
     * 新增用户
     * 很多人会把这个 int 类型的返回值当作数据库返回的主键的值，它其实是执行的 SQL 影响的行数，这个值和日志中的 Updates:1 是一致的。也就是说，这个 INSERT 语句影响了数据库
     * 中的 1 行数据。如果是批量插入、批量更新、批量删除，这里的数字会是插入的数据个数、更新的数据个数。一般在数据库管理软件中，执行 SQL 语句时，这些工具都会显示影响的行数。
     * @param sysUser
     * @return
     */
    int insert(SysUser sysUser);

    /**
     * 新增用户 - 使用 useGeneratedKeys 方式
     * @param sysUser
     * @return
     */
    int insert2(SysUser sysUser);

    /**
     * 新增用户 - 使用 selectKey 方式
     * @param sysUser
     * @return
     */
    int insert3(SysUser sysUser);

    /**
     * 根据主键更新
     * @param sysUser
     * @return
     */
    int updateById(SysUser sysUser);

    /**
     * 通过主键删除
     * 根据主键删除数据的时候，如果主键只有一个字段，那么就可以像这个方法一样使用一个参数 id。注意接口中 int deleteById(Long id);方法的参数类型为 Long id，
     * 如果将参数类型修改如下，也是正确的：
     * int deleteById(SysUser sysUser);
     * 接口这样修改后，对应的 XML 中的方法不需要做任何修改。
     * @param id
     * @return
     */
    int deleteById(Long id);

    /**
     * 通过对象删除
     * @param sysUser
     * @return
     */
    int deleteById(SysUser sysUser);

    /**
     * 根据用户 id 和角色的 enabled 状态获取用户的角色
     * @param userId
     * @param enabled
     * @return
     */
    List<SysRole> selectRolesByUserIdAndRoleEnabled(Long userId, Integer enabled);

    /**
     * 在接口方法的参数前添加 @Param 的方式根据用户 id 和角色的 enabled 状态获取用户的角色。
     * 给参数配置 @Param 注解后，MyBatis 就会自动将参数封装成 Map 类型，@Param 注解值会作为 Map 中的 key，因此在 SQL 部分就可以通过配置的注解值来使用参数。
     * @param userId
     * @param enabled
     * @return
     */
    List<SysRole> selectRolesByUserIdAndRoleEnabled4Annotation(
            @Param("userId") Long userId,
            @Param("enabled") Integer enabled);

    /**
     * 使用 @Param 注解以及当参数类型是一些 JavaBean 的时候
     * @param sysUser
     * @param role
     * @return
     */
    List<SysRole> selectRolesByUserIdAndRoleEnabled4AnnotationWithJavaBean(
            @Param("user") SysUser sysUser,
            @Param("role") SysRole role);
}
